/*
 * Copyright (c) 2010 CCX(China) Co.,Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * CCX(China) Co.,Ltd. ("Confidential Information").
 * It may not be copied or reproduced in any manner without the express 
 * written permission of CCX(China) Co.,Ltd.
 *
 * Author: zhaoshujin
 * Date: 2011-6-2 下午06:08:58
 */
package com.hash;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author zhaoshujin
 * 
 */
public class TreeMapDemo {

	private static Logger logger = LoggerFactory.getLogger(TreeMapDemo.class);

	public SortedMap<Long, String> InitTreeMap() {

		// memcached 服务端名称(个数)
		String[] nodes = { "node01", "node02", "node03" };

		// continuum划分组数
		int copies = 500;

		SortedMap<Long, String> allNodes = new TreeMap<Long, String>();

		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			for (String str : nodes) {

				for (int i = 0; i < copies; i++) {

					md5.reset();
					md5.update((str + i).getBytes("UTF-8"));
					byte[] digest = md5.digest();

					// Md5是一个16字节长度的数组，将16字节的数组每四个字节一组，
					// 分别对应一个虚拟结点，这就是为什么上面把虚拟结点四个划分一组的原因
					for (int h = 0; h < 4; h++) {

						// 对于每四个字节，组成一个long值数值，做为这个虚拟节点的在环中的惟一key
						Long k = ((long) (digest[3 + h * 4] & 0xFF) << 24) | ((long) (digest[2 + h * 4] & 0xFF) << 16)
								| ((long) (digest[1 + h * 4] & 0xFF) << 8) | (digest[h * 4] & 0xFF);

						allNodes.put(k, str);
					}
				}
			}
		} catch (NoSuchAlgorithmException e) {

			logger.error("No md5 algorithm found...");
			throw new IllegalStateException("No md5 algorithm found...");

		}catch (UnsupportedEncodingException e) {
			throw new RuntimeException("Unknown string ... " , e);
		}

		return allNodes;

	}

	public static void main(String[] args) {

		TreeMapDemo tmd = new TreeMapDemo();

		SortedMap<Long, String> allNodes = tmd.InitTreeMap();

		Set<Map.Entry<Long, String>> set = allNodes.entrySet();
		int i = 0;
		for (Iterator<Map.Entry<Long, String>> it = set.iterator(); it.hasNext();) {
			Map.Entry<Long, String> entry = (Map.Entry<Long, String>) it.next();
			System.out.println(++i + ": " + entry.getKey() + "--->" + entry.getValue());
		}

	}

}
